package com.atguigu.gmall.realtime.utils

import java.lang.reflect.{Field, Method}

import javax.lang.model.element.Modifier

import scala.util.control.Breaks

/**
 * 对象拷贝工具类，将源对象的属性拷贝到目标对象的属性上
 * 使用前提，对象属性名一样
 *
 */
object MyBeanUtils {
  //将src中对应的属性拷贝到dest对应的属性
  //利用反射
  def copyFiled(srcObj : AnyRef,destObj : AnyRef) : Unit = {
    //1.先判断两个对象是否为空
    if(srcObj == null || destObj ==null){
      return
    }
    //2.获取源对象的所有属性
    val srcFileds: Array[Field] = srcObj.getClass.getDeclaredFields

    //3. 迭代每个属性，完成拷贝
    for (srcFiled <- srcFileds) {
      srcFiled.setAccessible(true)
      //判断目标对象中是否有这个属性和是否为final

      Breaks.breakable(
        try {
          val destField: Field = destObj.getClass.getDeclaredField(srcFiled.getName)
          if(destField.getModifiers.equals(Modifier.FINAL)){
            Breaks.break()
          }
          //拼接get方法名，获取get方法
          
          val getFiledName: String = srcFiled.getName
          val getMethod: Method = srcObj.getClass.getDeclaredMethod(getFiledName)
          val fieldValue: AnyRef = getMethod.invoke(srcObj)

          //拼接set方法名，获取set方法
          val setMethodName: String = srcFiled.getName + "_$eq"
          val setMethod: Method = destObj.getClass.getDeclaredMethod(setMethodName,destField.getType)
          setMethod.invoke(destObj,fieldValue)

        } catch {
          case ex : Exception => Breaks.break()
        }
      )
    }

  }

}
